package com.asa.fushu.basehanshu;

import com.asa.HanShu2;
import com.asa.fushu.bean.Eulerformula;
import com.asa.fushu.bean.Fushu;
import com.asa.fushu.bean.Fushu_EXI;
import com.asa.fushu.bean.HanShu_Fu;

/**
  *	 	初等函数
  * 	复数域上的一些基本函数，把fanc(z)=v(z)+u(z)i,函数写成这种形式的转换
  * @author asa
  *
  */
public class Fushu_Hanshu_Create {
	

	/**
	 * 	指数函数
	 * exp(z) = exp(x+yi) = exp(x)*exp(yi)
	 * 
	 */
	public static HanShu_Fu exp() {

		HanShu2 u = new HanShu2() {
			
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				double real = x;
				double im = y;
				
				Fushu_EXI exp_yi = new Fushu_EXI(); 
				exp_yi.r=Math.exp(real);
				exp_yi.x = im;
				final Fushu ei = Eulerformula.ei(exp_yi);
				
				return ei.getReal();
			}
		};
		
		HanShu2 v = new HanShu2() {
			
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				double real = x;
				double im = y;
				
				Fushu_EXI exp_yi = new Fushu_EXI(); 
				exp_yi.r=Math.exp(real);
				exp_yi.x = im;
				final Fushu ei = Eulerformula.ei(exp_yi);
				
				return ei.getIm();
			}
		};
		HanShu_Fu result = new HanShu_Fu(u, v);
		
		return result;
	}
	
	
	
	
	
	
	

	/**
	 * 对数函数
	 * log(z) = log(x+yi) = log(|x*x+y*y|) + (arg(z)+2Math.PI*n)
	 * @param n	第几俯角
	 * @return
	 */
	public static HanShu_Fu log(final int n) {
		
		
		HanShu2 u = new HanShu2() {
			
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				
				return Math.log(Math.sqrt(x*x+y*y));
			}
		};
		
		HanShu2 v = new HanShu2() {
			
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				double r = Math.sqrt(x*x+y*y);
				double cos = x/r;
				double sin = y/r;
				
				double acos = Math.acos(cos);

				if (sin<0) {//这样没问题，挺好的
					acos = acos + Math.PI;
				}
				
				return acos + 2*Math.PI*n;
			}
		};
		HanShu_Fu result = new HanShu_Fu(u, v);
		
		return result;
		
		
		
	}

	
	
	
	/**
	 * 	复指数
	 * z^c = exp(c*log(z))
	 * 	当c是整数的时候，其实是很好理解的，无非就是z累乘
	 * 	如果c是一根复数呢？
	 * 	这就是这个方法要解决的问题
	 * 
	 */

	public static HanShu_Fu z_c(final Fushu c,final int n) {//实现方法感觉不太优雅，有点耗性能，但要优雅又要动脑子，暂时懒得动了
		
		HanShu2 u = new HanShu2() {
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				HanShu_Fu log = log(n);
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				

				Fushu hanshu = log.hanshu(z);

				Fushu mul = c.mul(hanshu);

				HanShu_Fu exp = exp();
				
				Fushu end = exp.hanshu(mul);
				
				return end.getReal();
			}
		};
		
		HanShu2 v = new HanShu2() {
			
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				HanShu_Fu log = log(n);
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				Fushu hanshu = log.hanshu(z);
				
				Fushu mul = c.mul(hanshu);
				
				HanShu_Fu exp = exp();
				
				Fushu end = exp.hanshu(mul);
				
				return end.getIm();
			}
		};
		
		
		
		HanShu_Fu result = new HanShu_Fu(u, v);
		
		return result;
	}
	
	/**
	 * 	复幂函数
	 * 	c^z = exp(z*log(c))
	 * 
	 * 
	 */
	public static HanShu_Fu c_z(final Fushu c,final int n) {
		
		HanShu2 u = new HanShu2() {
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				HanShu_Fu log = log(n);
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				

				Fushu hanshu = log.hanshu(c);

				Fushu mul = z.mul(hanshu);

				HanShu_Fu exp = exp();
				
				Fushu end = exp.hanshu(mul);
				
				return end.getReal();
			}
		};
		
		HanShu2 v = new HanShu2() {
			
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				HanShu_Fu log = log(n);
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				Fushu hanshu = log.hanshu(c);
				
				Fushu mul = z.mul(hanshu);
				
				HanShu_Fu exp = exp();
				
				Fushu end = exp.hanshu(mul);
				
				return end.getIm();
			}
		};
		
		
		
		HanShu_Fu result = new HanShu_Fu(u, v);
		
		return result;
		
		
				
	}

	
	
	
	
	
	
	
	/**
	 * 	正弦函数
	 * @return
	 */
	public static HanShu_Fu sin() {
		
		HanShu2 u = new HanShu2() {
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				Fushu i = new Fushu();
				i.real = 0;
				i.im = 1;
				
				
				HanShu_Fu exp = exp();
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				
				Fushu com2 = new Fushu();
				com2.real = -1;
				com2.im = 0;
				Fushu mul = z.mul(com2);
				
				
				Fushu hanshu1 = exp.hanshu(z.mul(i));
				hanshu1.shownumber();
				Fushu hanshu2 = exp.hanshu(mul.mul(i));
				hanshu2.shownumber();

				Fushu sub = hanshu1.sub(hanshu2);
				sub.shownumber();

				com2.real = 0;
				com2.im = 2;
				Fushu divide = sub.divide(com2);
				
				
				return divide.getReal();
			}
		};
		
		HanShu2 v = new HanShu2() {
			
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				Fushu i = new Fushu();
				i.real = 0;
				i.im = 1;
				
				HanShu_Fu exp = exp();
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				
				Fushu com2 = new Fushu();
				com2.real = -1;
				com2.im = 0;
				Fushu mul = z.mul(com2);
				
				
				Fushu hanshu1 = exp.hanshu(z.mul(i));
				
				Fushu hanshu2 = exp.hanshu(mul.mul(i));
				
				Fushu sub = hanshu1.sub(hanshu2);
				com2.real = 0;
				com2.im = 2;
				Fushu divide = sub.divide(com2);
				
				
				return divide.getIm();
			}
		};
		
		
		HanShu_Fu result = new HanShu_Fu(u, v);
		
		return result;
		
		
	}

	/**
	 * 	余弦函数
	 * @return
	 */
	public static HanShu_Fu cos() {
		
		HanShu2 u = new HanShu2() {
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				Fushu i = new Fushu();
				i.real = 0;
				i.im = 1;
				
				
				HanShu_Fu exp = exp();
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				
				Fushu com2 = new Fushu();
				com2.real = -1;
				com2.im = 0;
				Fushu mul = z.mul(com2);
				
				
				Fushu hanshu1 = exp.hanshu(z.mul(i));
				hanshu1.shownumber();
				Fushu hanshu2 = exp.hanshu(mul.mul(i));
				hanshu2.shownumber();

				Fushu add = hanshu1.add(hanshu2);
				add.shownumber();

				com2.real = 2;
				com2.im = 0;
				Fushu divide = add.divide(com2);
				
				
				return divide.getReal();
			}
		};
		
		HanShu2 v = new HanShu2() {
			
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub
				Fushu i = new Fushu();
				i.real = 0;
				i.im = 1;
				
				HanShu_Fu exp = exp();
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				
				Fushu com2 = new Fushu();
				com2.real = -1;
				com2.im = 0;
				Fushu mul = z.mul(com2);
				
				
				Fushu hanshu1 = exp.hanshu(z.mul(i));
				
				Fushu hanshu2 = exp.hanshu(mul.mul(i));
				
				Fushu add = hanshu1.add(hanshu2);
				com2.real = 2;
				com2.im = 0;
				Fushu divide = add.divide(com2);
				
				
				return divide.getIm();
			}
		};
		
		
		HanShu_Fu result = new HanShu_Fu(u, v);
		
		return result;
		
		
	}
	
	

	
	
	
	
	/**
	 * 	双曲正弦函数
	 * @return
	 */
	public static HanShu_Fu sinh() {
		
		HanShu2 u = new HanShu2() {
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub

				HanShu_Fu exp = exp();
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				
				Fushu com2 = new Fushu();
				com2.real = -1;
				com2.im = 0;
				Fushu mul = z.mul(com2);
				
				
				Fushu hanshu1 = exp.hanshu(z);
				hanshu1.shownumber();
				Fushu hanshu2 = exp.hanshu(mul);
				hanshu2.shownumber();

				Fushu sub = hanshu1.sub(hanshu2);
				sub.shownumber();

				com2.real = 0;
				com2.im = 2;
				Fushu divide = sub.divide(com2);
				
				
				return divide.getReal();
			}
		};
		
		HanShu2 v = new HanShu2() {
			
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub

				
				HanShu_Fu exp = exp();
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				
				Fushu com2 = new Fushu();
				com2.real = -1;
				com2.im = 0;
				Fushu mul = z.mul(com2);
				
				
				Fushu hanshu1 = exp.hanshu(z);
				
				Fushu hanshu2 = exp.hanshu(mul);
				
				Fushu sub = hanshu1.sub(hanshu2);
				com2.real = 0;
				com2.im = 2;
				Fushu divide = sub.divide(com2);
				
				
				return divide.getIm();
			}
		};
		
		
		HanShu_Fu result = new HanShu_Fu(u, v);
		
		return result;
		
		
	}
	
	/**
	 * 	双曲余弦函数
	 * @return
	 */
	public static HanShu_Fu cosh() {
		
		HanShu2 u = new HanShu2() {
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub

				
				
				HanShu_Fu exp = exp();
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				
				Fushu com2 = new Fushu();
				com2.real = -1;
				com2.im = 0;
				Fushu mul = z.mul(com2);
				
				
				Fushu hanshu1 = exp.hanshu(z);
				hanshu1.shownumber();
				Fushu hanshu2 = exp.hanshu(mul);
				hanshu2.shownumber();

				Fushu add = hanshu1.add(hanshu2);
				add.shownumber();

				com2.real = 2;
				com2.im = 0;
				Fushu divide = add.divide(com2);
				
				
				return divide.getReal();
			}
		};
		
		HanShu2 v = new HanShu2() {
			
			@Override
			public double hanshu(double t, double x, double y) {
				// TODO Auto-generated method stub
				return 0;
			}
			
			@Override
			public double hanshu(double x, double y) {
				// TODO Auto-generated method stub

				
				HanShu_Fu exp = exp();
				
				Fushu z = new Fushu();
				z.real = x;
				z.im = y;
				
				Fushu com2 = new Fushu();
				com2.real = -1;
				com2.im = 0;
				Fushu mul = z.mul(com2);
				
				
				Fushu hanshu1 = exp.hanshu(z);
				
				Fushu hanshu2 = exp.hanshu(mul);
				
				Fushu add = hanshu1.add(hanshu2);
				com2.real = 2;
				com2.im = 0;
				Fushu divide = add.divide(com2);
				
				
				return divide.getIm();
			}
		};
		
		
		HanShu_Fu result = new HanShu_Fu(u, v);
		
		return result;
		
		
	}
	
	/**
	 * 	反三角函数和反三曲函数，2X3，还要写六个函数，天哪，每个还贼复杂，不太想写
	 * 
	 */
	
	
	
	
	
	
	public static void main(String[] args) {
		
		Fushu z = new Fushu();
		z.real=0;
		z.im = 1;
		Fushu c = new Fushu();
		c.real=0;
		c.im = -2;
		
		HanShu_Fu z_c = z_c(c,0);
		Fushu hanshu = z_c.hanshu(z);
		
		hanshu.shownumber();
		System.out.println();
		double exp = Math.exp(5*Math.PI);
		System.out.println(exp);
		
		
////		HanShu_Fu log = log();
////		Fushu hanshu = log.hanshu(z);
////		hanshu.shownumber();
////		System.out.println();
////		
////		System.out.println(Math.PI/2);
////		
////		
////		
//		HanShu_Fu exp = exp();
//		Fushu hanshu2 = exp.hanshu(z);
//		
//		hanshu2.shownumber();
		System.out.println("========================");
		
		Fushu sin_z = new Fushu();
		sin_z.real=Math.PI;
		sin_z.im=0;
		
		
		HanShu_Fu sin = sin();
		Fushu hanshu2 = sin.hanshu(sin_z);
		hanshu2.shownumber();
		
		System.out.println(Math.sin(sin_z.real));
		
		
		
		System.out.println("-----------");
		
		Fushu i = new Fushu();
		i.real=0;
		i.im=2;
		
		Fushu divide = i.divide(i, i);
		divide.shownumber();
		
		HanShu_Fu cos = cos();
		Fushu hanshu3 = cos.hanshu(sin_z);
		hanshu3.shownumber();
		

	}
	
	
	
	
	
	
	
	
	
	
	
	
	

}
